package jp.hoge.RSSReader;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.Toast;

public class RSSReaderMainMenu extends Activity {
	/** Called when the activity is first created. */
	// スレッドのスタートを監視
	private static AtomicBoolean mFlg_Thread = new AtomicBoolean(true);
	// DB更新状況≒RSS取得状況
	enum CheckState {
		UPDATE,			// 更新あり
		NO_UPDATE,		// 更新なし
		NO_CONNECTION	// 接続なし
	};
	// スレッド実行結果の通知フラグ
	private CheckState mCheckFlg = CheckState.NO_CONNECTION;
	// RSSフィードのURL
	public static final String RSS_FEED_URL = "http://www.oesf.jp/modules/news/index.php?page=rss";

	// デバッグ用のコメントタグ
	public static final String TAG = "RSSReader";
	
	Bundle mBundle = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		Log.v(TAG, "onCreate");
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.main);

		// オプションメニュー制御フラグ　オン
//		mFlg_Thread.set(true);
	}

	// 一覧画面へ遷移
	public void onClickListButton(View v) {
		Intent intent = new Intent(this, RSSReaderList.class);
		startActivity(intent);
	}

	// オプションメニュー表示
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		boolean bl = super.onCreateOptionsMenu(menu);
		MenuInflater mi = getMenuInflater();
		mi.inflate(R.menu.main_menu, menu);
		return bl;
	}
	// オプションメニュー動作
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// スレッド制御　オンなら開始
		Toast.makeText(getApplicationContext(), getString(R.string.update),
				Toast.LENGTH_SHORT).show();
		if (mFlg_Thread.get()) {
			mFlg_Thread.set(false);
			new RSSReaderAsync().execute(RSS_FEED_URL);
		}
		return true;
	}

	public class RSSReaderAsync extends AsyncTask<String, RowModel, String> {
		// 接続時間
		final int TIMEOUT_TIME = 30000;
		// テスト確認用接続時間
//		final int TIMEOUT_TIME = 5000;

		// 取得したRSSの解析情報
		List<RowModel> rowModelList = new ArrayList<RowModel>();

		SQLiteDatabase db = null;
		RSSReaderSQLHelper rsshelper = new RSSReaderSQLHelper(
				getApplicationContext());

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			setProgressBarIndeterminateVisibility(true);
			// DBオープン（postでクローズ）
			db = rsshelper.getWritableDatabase();
		}

		@Override
		protected String doInBackground(String... params) {

			// RSS取得
			InputStream is = null;
			ParseXml parseXml = new ParseXml();
			try {
				// 解析対象のストリームを取得する
				URL url = new URL(params[0]);
				// テスト用
//				URL url = new URL("http://123.123.12.123");
//				is = getApplicationContext().getAssets().open("sample.xml");
//				is = getApplicationContext().getAssets().open("sample02.xml");

                // タイムアウトまでの時間を設定
                HttpURLConnection connection;
				try {
					connection = (HttpURLConnection) url.openConnection();
					connection.setConnectTimeout(TIMEOUT_TIME);
					try {
						is = connection.getInputStream();
						// 200 OKが返ってきた場合のみ、次の処理へ進む
						if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
							// 解析開始
							rowModelList = parseXml.ParseXmlPullparser(is);
							// 配列逆転
							Collections.reverse(rowModelList);
							// 登録件数が上限を超えていれば削除
							RecordUpdateCheck(parseXml);
							// レコードの挿入
							for (RowModel r : rowModelList) {
								SQLInsert(r);
							}
						}
					} catch (Exception e_getis){
						// ストリームが取得できなかった場合(IOException)
						// タイムアウトが発生した場合(SocketExpception)
						Log.v(TAG, Log.getStackTraceString(e_getis));
					} finally {
						if (is != null) {
							try {
								is.close();
							} catch (IOException e_close) {
								Log.v(TAG, Log.getStackTraceString(e_close));
							}
						}
					}
				} catch (IOException e_open) {
					// openConnection対応:何らかの理由で取得したストリームを開けなかった場合
					Log.v(TAG, Log.getStackTraceString(e_open));
				}
			} catch (MalformedURLException e_url) {
				// URL()対応
				Log.v(TAG, Log.getStackTraceString(e_url));
			}
			return null;
		}


		private void RecordUpdateCheck(ParseXml parseXml) {
			Cursor cursor = null;
			try {
				cursor = db.query(RSSReaderSQLHelper.TABLE_NAME, new String[] {
						"last_build_date", "rss_add_date" }, null, null, null,
						null, null);

				// レコード件数取得
				if (cursor != null) {
					if (!cursor.moveToFirst()) {
						// 登録0件のため新規作成
					} else {
						// レコード削除
						DeleteRecord(cursor);
					}
				}
				cursor.close();
			} catch (Exception e) {
				Log.v(TAG, Log.getStackTraceString(e));
			}
		}

		/**
		 * レコードのチェック 上限件数を超えていれば削除を行う
		 *
		 * @param cursor
		 */
		private void DeleteRecord(Cursor cursor) {

			int resultCount = cursor.getCount();
			if (resultCount > RSSReaderSQLHelper.DB_SIZE_MAX) {
				List<String> strlist = new ArrayList<String>();
				cursor.moveToFirst();
				do {
					strlist.add(cursor.getString(cursor
							.getColumnIndex("rss_add_date")));
				} while (cursor.moveToNext());
				Collections.sort(strlist);
				// ソートの結果、配列の先頭が一番小さい値になっていた
				// これをキーにしてdelete
				db.delete(
						RSSReaderSQLHelper.TABLE_NAME,
						"rss_add_date<"
								+ strlist.get(resultCount
										- RSSReaderSQLHelper.DB_SIZE_MAX), null);
			}
		}

		/**
		 * レコードの重複をチェックし、存在しなければinsert
		 *
		 * @param r
		 */
		private void SQLInsert(RowModel r) {
			// "link"情報内に":"が含まれているため、下の方式でのクエリーでないとエラー
			Cursor c = db.query("OESF_RSS_TABLE", null, "link=?",
					new String[] { r.getLink() }, null, null, null);

			// falseかつfalseっていうのは有り得ないよね？
			if ((c != null) && !c.moveToFirst()) {
				mCheckFlg = CheckState.UPDATE;
				// insertデータの準備
				ContentValues cv = new ContentValues();
				cv.put("title", r.getTitle());
				cv.put("link", r.getLink());
				cv.put("date", r.getDate());
				cv.put("description", r.getDescription());
				cv.put("last_build_date", r.getLast_Build_Date());
				// タイムスタンプの追加
				r.setRss_Add_Date(getTimeStampNow());
				cv.put("rss_add_date", r.getRss_Add_Date());

				// データを追加する
				long rowId = db.insert("OESF_RSS_TABLE", null, cv);
				Log.v(TAG, "RowID :" + rowId);
				if (rowId == -1) {
					Log.v("AddActivity", "insert failed.");
				}
			} else {
				mCheckFlg = CheckState.NO_UPDATE;
			}
			c.close();
		}

		/**
		 * 現在時刻を取得し文字列で返す
		 *
		 * @return　String
		 */
		private String getTimeStampNow() {

			Date date = new Date();
			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
			String str = new String(df.format(date));
			return str;
		}

		@Override
		protected void onPostExecute(String result) {
			setProgressBarIndeterminateVisibility(false);
			mFlg_Thread.set(true);
			if (CheckState.UPDATE == mCheckFlg) {

				// 更新完了通知
				NotificationManager mNM;
				mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

				// 通知内容を設定
				Notification n = new Notification();
				n.icon = R.drawable.icon;
				n.tickerText = getString(R.string.update_notification);
				n.when = System.currentTimeMillis();
				n.flags = Notification.FLAG_AUTO_CANCEL;

				Context context = getApplicationContext(); // application
															// Context
				CharSequence contentTitle = getString(R.string.app_name); // expanded
																			// message
																			// title
				CharSequence contentText = getString(R.string.update_comlete); // expanded
																				// message
																				// text

				// 遷移先を一覧画面に設定
				Intent i = new Intent(context, RSSReaderList.class);
				PendingIntent pend = PendingIntent.getActivity(context, 0, i,
						Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
				n.setLatestEventInfo(getApplicationContext(), contentTitle,
						contentText, pend);
				int notificationId = R.string.app_name;

				// 通知発行
				mNM.notify(notificationId, n);
			} else {
				showToast(mCheckFlg);
			}
			// DBクローズ
			rsshelper.close();
		}

	}

	private void showToast (CheckState checkstate){
		if (CheckState.NO_CONNECTION == checkstate) {
			Toast.makeText(getApplicationContext(), R.string.no_connect, Toast.LENGTH_SHORT).show();
		} else if(CheckState.NO_UPDATE == checkstate){
			Toast.makeText(getApplicationContext(), R.string.no_comlete, Toast.LENGTH_SHORT).show();
		}
	}

}